算額(その1034)
五十五 花泉町老松 林観世音堂 文政7年(1824)
山村善夫:現存 岩手の算額,昭和52年1月30日,熊谷印刷,盛岡市.
http://www.wasan.jp/yamamura/yamamura.html
正方形の中に二等辺三角形と大円,中円,小円,甲円,乙円,丙円を容れる。小円の直径が 1 寸のとき,丙円の直径はいかほどか。
正方形の一辺の長さを 2a
大円の半径と中心座標を r1, (0, r1)
中円の半径と中心座標を r2, (0, 2r1 + r2
小円の半径と中心座標を r3, (0, 2r1 + 2r2 + r3)
甲円の半径と中心座標を r4, (a - r4, 2a - r4)
乙円の半径と中心座標を r5, (a - r5, y5)
丙円の半径と中心座標を r6, (a - r6, y6)
とおき,以下の連立方程式を解く。
include("julia-source.txt");
using SymPy
@syms a::positive, r1::positive, r2::positive,
r3::positive, r4::positive, r5::positive,
y5::positive, r6::positive, y6::positive
eq1 = r1/(2a - r1) - 1/√Sym(5)
eq2 = r2/(2a - 2r1 - r2) - 1/√Sym(5)
eq3 = r3/(2a - 2r1 - 2r2 - r3) - 1/√Sym(5)
# eq4 = dist2(0, 2a, a, 0, a - r4, 2a - r4, r4)
# eq5 = dist2(0, 2a, a, 0, a - r5, y5, r5)
# eq6 = dist2(0, 2a, a, 0, a - r6, y6, r6)
eq4 = a + 2a - sqrt(a^2 + 4a^2) - 2r4
eq5 = r5/y5 - r6/y6
eq6 = r4/(2a - r4) - r6/y6
eq7 = (r4 - r5)^2 + (2a - r4 - y5)^2 - (r4 + r5)^2 |> expand
eq8 = (r5 - r6)^2 + (y5 - y6)^2 - (r5 + r6)^2 |> expand
# solve([eq1, eq2, eq3, eq4, eq5, eq6, eq7, eq8],
# (a, r1, r2, r4, r5, y5, r6, y6))
1. a, r1, r2 を求めるのは簡単である
連立方程式は相互に独立なものが混ざっているので,逐次解いてゆくのが良策である。
正方形の一辺,二等辺三角形内の大円,中円,小円の半径を求めるためには eq1, eq2, eq3 の連立方程式を解けばよい。a, r1, r2 は与えられた r3 の関数(倍数)で表現される。
res1 = solve([eq1, eq2, eq3], (r1, r2, a))
#= a =# res1[a] |> println
r3*(11 + 5*sqrt(5))/2
#= r1 =# res1[r1] |> println
r3*(3*sqrt(5) + 7)/2
#= r2 =# res1[r2] |> println
r3*(sqrt(5) + 3)/2
2. r4 は有名な「直角三角形に内接する円の直径」で求める
eq4 により,これも r3 の関数(倍数)で表現できる。式中に出ている a は前段階で求められているので,その定義を使う。
@syms a::positive, r1::positive, r2::positive,
r3::positive, r4::positive, r5::positive,
y5::positive, r6::positive, y6::positive
a = r3*(11 + 5*sqrt(Sym(5)))/2
eq4 = a + 2a - sqrt(a^2 + 4a^2) - 2r4
ans_r4 = solve(eq4, r4)[1] |> simplify
ans_r4 |> println
r3*(2 + sqrt(5))
3. r5, y5, r6, y6 を求める
eq5, eq6, eq7, eq8 の 4 元連立方程式を解くこともできるが,SymPy では結果の式が複雑になり簡約化もできないので,これらも逐次解くようにする。
using SymPy
@syms a::positive, r1::positive, r2::positive,
r3::positive, r4::positive, r5::positive,
y5::positive, r6::positive, y6::positive
r4 = r3*(2 + sqrt(Sym(5)))
eq5 = r5/y5 - r6/y6
eq6 = r4/(2a - r4) - r6/y6
eq7 = (r4 - r5)^2 + (2a - r4 - y5)^2 - (r4 + r5)^2 |> expand
eq8 = (r5 - r6)^2 + (y5 - y6)^2 - (r5 + r6)^2 |> expand;
3.1. y5, y6 を求める
eq5, eq6 を解いて y5, y6 を求める。解の式には a, r4, r5, r6 が含まれる。a, r4 は前段階までで求められているが,r5, r6 はまだ未知数である。
res2 = solve([eq5, eq6], (y5, y6))
#= y5 =# ans_y5 = res2[y5]
ans_y5 |> println
r5*(2*a - r4)/r4
#= y6 =# ans_y6 = res2[y6]
ans_y6 |> println
r6*(2*a - r4)/r4
3.2. r5, r6 を求める
前段階で求められた y5, y6 を eq7 に代入すると,これまでに求められている a, r4, 未知数 r5 の式になるので,r5 を求めることができる。
eq7 = eq7(y5 => ans_y5, y6 => ans_y6) |> simplify
eq7 |> println
4*a^2 - 8*a^2*r5/r4 - 4*a*r4 + 8*a*r5 + r4^2 - 6*r4*r5 + r5^2*(2*a - r4)^2/r4^2
ans_r5 = solve(eq7, r5)[1] # 1 of 2
ans_r5 |> println
r4*(4*a^2 - 4*a*r4 + 3*r4^2 - 2*r4*sqrt(4*a^2 - 4*a*r4 + 2*r4^2))/(4*a^2 - 4*a*r4 + r4^2)
同様に,前段階で求められた y5, y6 を eq8 に代入すると,これまでに求められている a, r4, r5, 未知数 r6 の式になるので,r6 を求めることができる。
eq8 = eq8(y5 => ans_y5, y6 => ans_y6) |> simplify
eq8 |> println
(-4*r4^2*r5*r6 + r5^2*(2*a - r4)^2 - 2*r5*r6*(2*a - r4)^2 + r6^2*(2*a - r4)^2)/r4^2
ans_r6 = solve(eq8, r6)[1] # 1 of 2
ans_r6 |> println
r5*(4*a^2 - 4*a*r4 + 3*r4^2 - 2*r4*sqrt(4*a^2 - 4*a*r4 + 2*r4^2))/(4*a^2 - 4*a*r4 + r4^2)
4. 連立方程式の解のまとめ
順次求めた結果をまとめると以下のようになる。
r3 は与えられた既知の数である。
r5 と r6,y5 と y6 を見ればわかるが,甲円,乙円,丙円,... の累円の半径,中心の y 座標は,前の円の定数倍になっている(等比級数である)。
@syms r3
s5 = √Sym(5)
r1 = r3*(3s5 + 7)/2
r2 = r3*(s5 + 3)/2
a = r3*(11 + 5s5)/2
r4 = a*(3 - s5)/2
r5 = r4*(4a^2 - 4a*r4 + 3r4^2 - 2r4*sqrt(4a^2 - 4a*r4 + 2r4^2))/(4a^2 - 4a*r4 + r4^2)
r6 = r5*(4a^2 - 4a*r4 + 3r4^2 - 2r4*sqrt(4a^2 - 4a*r4 + 2r4^2))/(4a^2 - 4a*r4 + r4^2)
y5 = r5*(2a - r4)/r4
y6 = r6*(2a - r4)/r4;
r6 はこの段階では非常に複雑な長い式になっている。
r6 |> display
SymPy により,r6 は以下のように簡約化できるが,後述の「術」による式は見た目は簡潔である。
r6 |> simplify |> (x -> x(sqrt(r3^2) => r3)) |> simplify |> println
r3*(-318 - 54*sqrt(25 - 5*sqrt(5)) + 118*sqrt(5 - sqrt(5)) + 145*sqrt(5))
(-318 - 54*sqrt(25 - 5*sqrt(5)) + 118*sqrt(5 - sqrt(5)) + 145*sqrt(5))
1.6618327599278473
丙円の直径は,小円の直径の 1.6618327599278473 倍である。
5. 数値解
単に数値解を求めるだけであれば,nlsolve() を用いて以下のようにすればよい。
using NLsolve
function nls(func, params...; ini = [0.0])
if typeof(ini) <: Number
r = nlsolve((vout, vin) -> vout[1] = func(vin[1], params..., [ini]), ftol=big"1e-40")
v = r.zero[1]
else
r = nlsolve((vout, vin)->vout .= func(vin, params...), ini, ftol=big"1e-40")
v = r.zero
end
return Float64.(v), r.f_converged
end;
function H(u)
(a, r1, r2, r4, r5, y5, r6, y6) = u
return [
r1/(2*a - r1) - sqrt(5)/5, # eq1
r2/(2*a - 2*r1 - r2) - sqrt(5)/5, # eq2
r3/(2*a - 2*r1 - 2*r2 - r3) - sqrt(5)/5, # eq3
-sqrt(5)*a + 3*a - 2*r4, # eq4
r5/y5 - r6/y6, # eq5
r4/(2*a - r4) - r6/y6, # eq6
(r4 - r5)^2 - (r4 + r5)^2 + (2*a - r4 - y5)^2, # eq7
(r5 - r6)^2 - (r5 + r6)^2 + (y5 - y6)^2, # eq8
]
end;
r3 = 1/2
iniv = BigFloat[5.5, 3.4, 1.3, 2.1, 1.3, 5.6, 0.8, 3.5]
res = nls(H, ini=iniv)
([5.545084971874738, 3.4270509831248432, 1.3090169943749477, 2.118033988749895, 1.326615669503669, 5.619634156033938, 0.83091637996395, 3.519818269145337], true)
6. 「術」による計算
術は,丙円の径を求める短い式を提示している。
山村の解説ではここでも,A^4 とすべきところを 4^4 と誤記している(結果は正しいが)。
@syms 小円径
天 = s5 + 2
A = (sqrt(天^2 + 1) - 1)/天
丙円径 = A^4*天*小円径
当然ながら,答えは前に示した解析解,数値解と一致する。
丙円径(小円径 => 1).evalf() |> println
1.66183275992790
この式を SymPy で簡約化すると以下のようになる。
得られる式は,前述した解析解の簡約化された数式と同じくらいの複雑さになる。
@syms d
丙円径 = apart(丙円径, d) |> simplify |> factor |> simplify
丙円径 |> println
小円径*(-140*sqrt(20*sqrt(5) + 50) - 318 + 145*sqrt(5) + 312*sqrt(4*sqrt(5) + 10))
(-140*sqrt(20*sqrt(5) + 50) - 318 + 145*sqrt(5) + 312*sqrt(4*sqrt(5) + 10)) |> println
1.6618327599280747
function draw(more=false)
pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
r3 = 1/2
# (a, r1, r2, r4, r5, y5, r6, y6) = [5.545084971874738, 3.4270509831248432, 1.3090169943749477, 2.118033988749895, 1.326615669503669, 5.619634156033938, 0.83091637996395, 3.519818269145337]
r1 = r3*(3√5 + 7)/2
r2 = r3*(√5 + 3)/2
a = r3*(11 + 5√5)/2
r4 = a*(3 - √5)/2
r5 = r4*(4a^2 - 4a*r4 + 3r4^2 - 2r4*sqrt(4a^2 - 4a*r4 + 2r4^2))/(4a^2 - 4a*r4 + r4^2)
r6 = r5*(4a^2 - 4a*r4 + 3r4^2 - 2r4*sqrt(4a^2 - 4a*r4 + 2r4^2))/(4a^2 - 4a*r4 + r4^2)
y5 = r5*(2a - r4)/r4
y6 = r6*(2a - r4)/r4
@printf("小円の直径が %g のとき,丙円の直径は %g である。\n", 2r3, 2r6)
plot([a, a, -a, -a, a], [0, 2a, 2a, 0, 0], color=:blue, lw=0.5)
plot!([-a, 0, a], [0, 2a, 0], color=:orange, lw=0.5)
circle(0, r1, r1)
circle(0, 2r1 + r2, r2, :green)
circle(0, 2r1 + 2r2 + r3, r3, :blue)
circle(a - r4, 2a - r4, r4, :magenta)
circle(a - r5, y5, r5, :brown)
circle(a - r6, y6, r6, :purple)
if more
delta = (fontheight = (ylims()[2]- ylims()[1]) / 500 * 10 * 2) /3 # size[2] * fontsize * 2
hline!([0], color=:gray80, lw=0.5)
vline!([0], color=:gray80, lw=0.5)
point(a - r4, 2a - r4, "(a-r4,2a-r4)")
#point(a - r5, y5, "(a-r5,y5)")
#point(a - r6, y6, "(a-r6,y6)")
end
end;